package com.servcice.impl;

import com.dao.ClazzDao;
import com.dao.ClazzForStudentDao;
import com.dao.RedisDao;
import com.dao.StudentDao;
import com.dto.BaseDto;
import com.dto.dataenum.MessageEnum;
import com.entity.Account;
import com.entity.Clazz;
import com.entity.Student;
import com.exception.CustomException;
import com.mapper.StudentMapper;
import com.page.PageInfo;
import com.servcice.StudentService;
import org.springframework.stereotype.Repository;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;
import java.util.Optional;

@Service("studentService")
@EnableTransactionManagement
public class StudentServiceImpl implements StudentService {
    @Resource
    StudentDao studentDao;
    @Resource
    ClazzForStudentDao clazzForStudentDao;
    @Resource
    RedisDao redisDao;

    public BaseDto<Student> getAll() throws Exception {

        BaseDto<Student> dto = new BaseDto<>(MessageEnum.SELECT_STUDENTALL_SUCCESS);
        dto.settList(studentDao.getAll());
        return dto;
    }

    public int addStudent(Student student) throws Exception {
        return studentDao.addStudent(student);
    }

    /**
     * 前2页存redis 2页以后的直接查询mysql，dao提供了2个查询方法，一个有缓存注解关联缓存，一个没有缓存注解不关联
     * @param pageInfo
     * @param cacheId
     * @return
     * @throws Exception
     */
    public BaseDto<Student> getStudentsByPage(PageInfo pageInfo,String cacheId) throws Exception {
        BaseDto<Student> dto = new BaseDto<>(MessageEnum.SELECT_STUDENTBYPAGE_SUCCESS);
        List<Student> students = pageInfo.getCurrPage()>2?studentDao.getStudentsByPage(pageInfo):studentDao.getStudentsByPage(pageInfo,cacheId);//如果大于2 不走缓存
        int itemCount = pageInfo.getCurrPage() > 2?pageInfo.getItemCount():studentDao.getItemCount("studentCount");//如果小于2，需要从缓存重新获取当前总记录数
        pageInfo.setItemCount(itemCount);
        dto.settList(students);
        dto.setObj(pageInfo);
        return dto;
    }
    public BaseDto<Student> searchStudentByName(String name,PageInfo pageInfo) throws Exception{
        BaseDto<Student> dto = new BaseDto<>(MessageEnum.SELECT_STUDENTBYPAGE_SUCCESS);
        List<Student> students = studentDao.searchStudentByName(name,pageInfo);
        //如果学生集合为空 抛出异常
       if(students.size() <= 0) {
           throw new CustomException(MessageEnum.SELECT_STUDENTSEARCH_FAIL.getMsg());
       }
        dto.settList(students);
        dto.setObj(pageInfo);
        return dto;
    }
    public BaseDto selectStudentWithScsAndCourse(String sno)throws Exception{
        BaseDto dto = new BaseDto<>(MessageEnum.SELECT_STUDENTBYSNOWITHSCS_SUCCESS);
        dto.setT(studentDao.selectStudentWithScsAndCourse(sno));
        return dto;
    }

    public Student selectStudentBySno(String sno){
        return studentDao.selectStudentBySno(sno);
    }

    /**
     * 学生转班 是一个涉及3条sql语句操作的逻辑，所以这个逻辑必须全部成功或者全部失败，必须使用事务
     * @param sno
     * @param newCno
     * @return
     */
    //指定事务的管理器，propagation定事务的传播行为，那些异常引发回滚rollbackFor
    @Transactional(value="transactionManager",propagation = Propagation.REQUIRED,rollbackFor={CustomException.class})
    public BaseDto  studentChangeClazz(String sno,String newCno)throws Exception{
      Student student = selectStudentBySno(sno);
      String oldCno = student.getCno();//拿到原来的班级号
        student.setCno(newCno);
        studentDao.updateStudentByCno(student);

        //完成旧班减员
        studentChangeClazz(oldCno,false);
         if(newCno.equals("090102")){
             throw  new CustomException(MessageEnum.SELECT_STUDENTCHANGECLAZZBYLOCKED_FAIL.getMsg());
         }
        //完成新班进班
        studentChangeClazz(newCno,true);
        redisDao.deleteKey("studentsByPage1");
        //默认全部成功，失败都抛异常
        return new BaseDto(200,MessageEnum.SELECT_STUDENTCHANGECLAZZ_SUCCESS.getMsg());
    }

    public boolean studentChangeClazz(String cno,boolean isJoin) throws Exception {
        Clazz clazz = clazzForStudentDao.getClazzByCno(cno);
        System.out.println(cno+"----------------" + clazz);
        int countno = clazz.getCountno() + (isJoin?1:-1);
        clazz.setCountno(countno);
        int result = clazzForStudentDao.updateByPrimaryKeySelective(clazz);
        return result>0?true:false;
    }

    public Student loginStudentByName(String name){
        return studentDao.loginStudentByName(name);
    }
    @Override
    public Account getAccountByAccountName(String name) {
        // TODO Auto-generated method stub
        System.out.println(name+" 123455");
        return loginStudentByName(name);
    }

}
